package net.homelinux.chaoswg.io.renga.krypto.animations.Shift;

import java.awt.GridLayout;
import java.util.Observable;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

import net.homelinux.chaoswg.io.higherorderfunctions.UnaryFunction;
import net.homelinux.chaoswg.io.renga.core.registries.GlobalPropertyRegistry;
import net.homelinux.chaoswg.io.renga.krypto.datatypes.vectors.BitVector;
import net.homelinux.chaoswg.io.renga.krypto.operations.vector.LeftShift;
import net.homelinux.chaoswg.io.renga.krypto.operations.vector.RightShift;

public class ShiftStateChanger extends Observable implements Runnable {
    JLabel firstOperandsDisplay;

    JLabel resultDisplay;
    JFrame jw;
    
    UnaryFunction<BitVector, BitVector> shift;
    
    final ShiftState initialState;
    
    public ShiftStateChanger (ShiftState initialState, int direction)  {
        this.initialState = initialState;
        
        shift = direction == ShiftAnimation.LEFT ? new LeftShift () : new RightShift ();

        jw = new JFrame (direction == ShiftAnimation.LEFT ? "Left" : "Right" + "Shift");
        jw.getContentPane().add(getPanel());
        jw.setLocationRelativeTo(null);
        
        jw.setSize(500, 100);
        
        
    }
    
    private JPanel getPanel() {
        JPanel toReturn = new JPanel (new GridLayout (2,1));
        toReturn.add (firstOperandsDisplay = new JLabel (initialState.getToRotate().toString()));
        toReturn.add (resultDisplay = new JLabel (initialState.getResult().toString()));

        firstOperandsDisplay.setHorizontalAlignment(JLabel.RIGHT);
        resultDisplay.setHorizontalAlignment(JLabel.RIGHT);

        toReturn.setBorder(new BevelBorder (BevelBorder.RAISED));

        return toReturn;
    }

    private void setNew () {
        firstOperandsDisplay.setText (initialState.getToRotate().toString());
        firstOperandsDisplay.paintImmediately(firstOperandsDisplay.getVisibleRect());
        resultDisplay.setText (initialState.getResult().toString());
        resultDisplay.paintImmediately(firstOperandsDisplay.getVisibleRect());
    }

    public void run() {
        int delay = ((Integer)GlobalPropertyRegistry.getGlobalPropertyRegistry().getProperty("animationSpeed")) * 100;

        jw.setVisible(true);

        setNew ();
        BitVector operand = initialState.getToRotate();
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {System.err.println ("ERR");}

        initialState.setResult(shift.apply(operand));

        setNew ();

        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}
    }

    public void close () {
        jw.dispose ();
    }
}
